/*
 * Copyright (c) 2013-2015 Travis Geiselbrecht
 *
 * Use of this source code is governed by a MIT-style
 * license that can be found in the LICENSE file or at
 * https://opensource.org/licenses/MIT
 */



#include <stdint.h>
#include <stdio.h>

#define  __ARM_TARGET_COPROC   0x5
#include <arm_acle.h>

#include "compiler.h"
#include "hcb_comn.h"
#include "tlsf.h"




/* heap init */
static tlsf_t  kheap;

void  free( void * ptr )
{
    tlsf_free( kheap, ptr );
    return;
}



void * malloc( size_t tsiz  )
{
    void * ptr;

    /**/
    ptr = tlsf_malloc( kheap, tsiz );
    return ptr;
}



#if   0

void *__aeabi_read_tp( void )
{
    static  uint64_t   temp;
    return (void *)&temp;
}

#endif



int  __perf_init( void )
{
	uint32_t  temp;

	/* PMINTENCLR: clear INT enable */
	temp = 0x80000003;
	__arm_mcr( 15, 0, temp, 9, 14, 2 );

	/* clear by PMCR */
	temp = 0x41051004;
	__arm_mcr( 15, 0, temp, 9, 12, 0 );

	/* PMSELR, PMCCFILTR */
	temp = 0x1F;
	__arm_mcr( 15, 0, temp, 9, 12, 5 );

	temp = 0x00000000;
	__arm_mcr( 15, 0, temp, 9, 13, 1 );

	/* enable, PMCNTENSET, count every clock */
	temp = 0x41051001;
	__arm_mcr( 15, 0, temp, 9, 12, 0 );
  
	temp = 0x80000000;
	__arm_mcr( 15, 0, temp, 9, 12, 1 );
  
	/**/
	return 0;
	
}


void __cpu_init( void )
{
	__perf_init();

	/* 200Mhz */
	// write_reg( BASE_AP_SYSCTL + 0x44,  0 );
	return;
}

extern  char  __bss_end__;

void __ccc_init( void )
{
	intptr_t  temp;

    /* 在 start.S 中, 把 0x178000 以上的内存分配给了各种 stack 使用. */
	temp = (intptr_t)&__bss_end__;
	temp = (temp + 15 ) & 0xFFFFFFF0;
	kheap = tlsf_create_with_pool( (void *)temp, (size_t)(0x178000 - temp) );
	
    /**/
    return;
}


extern  int  uart_earyly_init( void );

void __soc_init( void )
{
    // arch_intc_init();
    uart_earyly_init();
    return;
}


void __my_init( void )
{
	/* cpu core, special init */
	__cpu_init();
	
	/* libc init */
	__ccc_init();

	/**/
	__soc_init();
	return;
}
